//
//  ViewController.m
//  ReflectionDemo
//
//  Created by GuochengLiu on 2016/12/12.
//  Copyright © 2016年 sumavision. All rights reserved.
//

#pragma clang diagnostic ignored "-Warc-performSelector-leaks"

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    
}

- (IBAction)onHitGoButton:(UIButton *)sender {
    
    NSString *path =  [[NSBundle mainBundle] pathForResource:@"remoteAction" ofType:@"json"];
    NSData *data = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:path]];
    
    NSDictionary *jsonDictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
    
    NSString *className = [jsonDictionary valueForKey:@"className"];
    
    Class class = NSClassFromString(className);
    
    ViewController *vc = [[class alloc] init];
    
    NSString *methodName = [jsonDictionary valueForKey:@"methodName"];
    
    SEL method = NSSelectorFromString(methodName);
    
    NSDictionary *propertyDict = [jsonDictionary valueForKey:@"properties"];
    
    [propertyDict enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
        if ([vc respondsToSelector:NSSelectorFromString(key)]) {
            [vc setValue:obj forKey:key];
        }
    }];
    
    [self.navigationController pushViewController:vc animated:YES];
    
    // If invoke the method without parameter or just one parameter, just use performSelector
    // use #pragma clang diagnostic ignored "-Warc-performSelector-leaks" to ignore warning

    if ([vc respondsToSelector:method]) {
        [vc performSelector:method];
    }
    
    
    // If the method has several parameters, use NSInvocation
    
    /* Uncomment this to see
    NSArray *parameters = [jsonDictionary valueForKey:@"methodParameters"];

    if ([vc respondsToSelector:method]) {
        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[vc methodSignatureForSelector:method]];
        [invocation setSelector:method];
        [invocation setTarget:vc];
        
        for (id parameter in parameters) {
            NSInteger index = [parameters indexOfObject:parameter] + 2;
            [invocation setArgument:&(parameter) atIndex:index];
        }
        
        [invocation invoke];
    }
    */
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


@end
